package yicr.panne;



import yicr.Form;
import yicr.GBC;
import yicr.untils.NslUtilCsv;
import yicr.untils.datetime.NslUtilDateTime;
import yicr.untils.gis.NslUtilGis;
import yicr.untils.gis.Polygon.NslPolygon;
import yicr.untils.gis.domain.NslPoint;
import yicr.untils.gis.domain.NslPointLong;
import yicr.untils.gis.geoHash.GeoHash;
import yicr.untils.gis.geoHash.NslUtilGeoHash;
import yicr.untils.gis.mif.UtilMapInfoMif;
import yicr.untils.gis.wireless.NslUtilWireless;
import yicr.untils.gis.wireless.WirelessCell;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;
import java.util.List;

/**
 * <h3>Title:</h3>
 * <p>
 *
 * <h3>Description</h3>
 * 面板分为2个层次：左1，右1，左1为 参数和按钮区域，右1为图片区域
 * 左1： 再分为上下两个区域，上为参数设置区域，下为按钮区域
 *
 * <h3>Author</h3>
 * <p>
 * Lin Shao
 *
 * @author Lin Shao
 * @version 1.0
 */
public class ImageCreationPane2 extends JPanel {
    private Form form=null;
    private int geohashColumnIndex;

    private static final int DEFAULT_WIDTH=740;
    private static final int DEFAULT_HEIGHT=340;


    private JLabel tipLabel1 =new JLabel("MR/OTT 输入路径:");
    private JLabel tipLabel2 = new JLabel(" 工参输入信息: ");
    private JLabel tipLabel3 =new JLabel("覆盖图输出路径: ");
    private JLabel tipLabel4 =new JLabel(" 生成图片数量: ");


    private JTextField textField1 =null;
    private JTextField textField2 =null;
    private JTextField textField3 =null;
    private JTextField textField4 =null;

    private JLabel unitLabel1 =new JLabel("");
    private JLabel unitLabel2 =new JLabel(" ");
    private JLabel unitLabel3 =new JLabel(" ");
    private JLabel unitLabel4 =new JLabel("");

    private String defaultTextField1 ="";
    private String defaultTextField2 ="";
    private String defaultTextField3 ="";
    private String defaultTextField4 ="0";


    private JButton button1 =null;
    private JButton calDataButton=null;

    private JFileChooser fileChooser=null;
    private String importFileAbsPath;

    private List<String> lineList =null;


    public ImageCreationPane2() throws URISyntaxException {
        initFont();

        lineList =new ArrayList<>();

        setSize(new Dimension(DEFAULT_WIDTH,DEFAULT_HEIGHT));
//        setResizable(false);

        fileChooser=new JFileChooser();

        FileFilter filter = new FileNameExtensionFilter(
                "Csv files", "csv");
        fileChooser.setFileFilter(filter);


        textField1 =new JTextField();
        textField2 =new JTextField();
        textField3 =new JTextField();
        textField4 =new JTextField();

        int textColumn=15;

        textField1.setColumns(textColumn);
        textField2.setColumns(textColumn);
        textField3.setColumns(textColumn);
        textField4.setColumns(textColumn);

        textField4.setEnabled(false);



        button1 =new JButton("构建覆盖图");
        calDataButton=new JButton("扫描Mif&Tab导出");





        textField1.setHorizontalAlignment(JTextField.CENTER);
        textField2.setHorizontalAlignment(JTextField.CENTER);
        textField3.setHorizontalAlignment(JTextField.CENTER);
        textField4.setHorizontalAlignment(JTextField.CENTER);

        textField1.setText(defaultTextField1+"");
        textField2.setText(defaultTextField2 +"");
        textField3.setText(defaultTextField3 +"");
        textField4.setText(defaultTextField4 +"");
        String imageAbsPath="d:/antenna_1.png";

        imageAbsPath=Thread.currentThread().getContextClassLoader().getResource("")+"\\tab2_img2.png";
        //imageAbsPath=Thread.currentThread().getContextClassLoader().getResource("")+"\\antenna_1.png";
        imageAbsPath=imageAbsPath.replace("file:","");

        //System.out.println(new File(imageAbsPath).getAbsolutePath());
        JLabel imageLabel=new JLabel(new ImageIcon(imageAbsPath));
        Border etched = BorderFactory.createEtchedBorder();
        imageLabel.setBorder(etched);

        JPanel parameterPanel=new JPanel();

        GridBagLayout gridBagLayoutOfParameterPanel=new GridBagLayout();

        parameterPanel.setLayout(gridBagLayoutOfParameterPanel);

        int top=20;
        int bottom=20;

        parameterPanel.add(tipLabel1,new GBC(0,0,1,1).setAnchor(GridBagConstraints.EAST).setInsets(top,30,15,20));
        parameterPanel.add(tipLabel2,new GBC(0,1,1,1).setAnchor(GridBagConstraints.EAST).setInsets(15,30,15,20));
        parameterPanel.add(tipLabel3,new GBC(0,2,1,1).setAnchor(GridBagConstraints.EAST).setInsets(15,30,15,20));
        parameterPanel.add(tipLabel4,new GBC(0,3,1,1).setAnchor(GridBagConstraints.EAST).setInsets(15,30,bottom,20));

        parameterPanel.add(textField1,new GBC(1,0,1,1).setAnchor(GridBagConstraints.EAST).setInsets(top,0,15,0));
        parameterPanel.add(textField2,new GBC(1,1,1,1).setAnchor(GridBagConstraints.EAST).setInsets(15,0,15,0));
        parameterPanel.add(textField3,new GBC(1,2,1,1).setAnchor(GridBagConstraints.EAST).setInsets(15,0,15,0));
        parameterPanel.add(textField4,new GBC(1,3,1,1).setAnchor(GridBagConstraints.EAST).setInsets(15,0,bottom,0));

        parameterPanel.add(unitLabel1,new GBC(2,0,1,1).setAnchor(GridBagConstraints.WEST).setInsets(top,5,15,10));
        parameterPanel.add(unitLabel2,new GBC(2,1,1,1).setAnchor(GridBagConstraints.WEST).setInsets(15,5,15,10));
        parameterPanel.add(unitLabel3,new GBC(2,2,1,1).setAnchor(GridBagConstraints.WEST).setInsets(15,5,15,10));
        parameterPanel.add(unitLabel4,new GBC(2,3,1,1).setAnchor(GridBagConstraints.WEST).setInsets(15,5,bottom,10));

        //Border etched = BorderFactory.createEtchedBorder();
        Border titled = BorderFactory.createTitledBorder(etched, "覆盖图构建参数设置");

        parameterPanel.setBorder(titled);


        GridBagLayout mainGridBagLayout=new GridBagLayout();

        setLayout(mainGridBagLayout);

        JPanel buttonPanel=new JPanel();
        buttonPanel.add(button1, new GBC(0,0,1,1).setAnchor(GridBagConstraints.CENTER).setInsets(10));


        add(parameterPanel,new GBC(0,0,2,1));

        add(buttonPanel,new GBC(0,1,2,1).setInsets(15));

        add(imageLabel,new GBC(2,0,1,2).setInsets(15,30,15,15));


        setScreenCenter();
        //pack();

        addEvents();
    }

    private void addEvents() {

        button1.addActionListener(e -> {
           String mrFilePath=textField1.getText();
           String cellInfoFilePath=textField2.getText();

           String imgOutputDirPath=textField3.getText();
           File mrFile=new File(mrFilePath);
           File cellInfoFile=new File(cellInfoFilePath);
           File imgOutputDir=new File(imgOutputDirPath);

           int imageAmount=0;

           if(mrFile.isFile() && cellInfoFile.isFile() && imgOutputDir.isDirectory()){
               try {
                   imageAmount=createImages(mrFilePath,cellInfoFilePath,imgOutputDirPath);
               } catch (IOException ex) {
                   throw new RuntimeException(ex);
               }

           }else{
               JOptionPane.showMessageDialog(ImageCreationPane2.this, "输入的路径参数不正确，请检查", "错误", JOptionPane.ERROR_MESSAGE);
               return;
           }
            textField4.setText(imageAmount+"");
            JOptionPane.showMessageDialog(null, "已生成覆盖图构建结果文件");
        });

    }

    private int createImages(String mrFilePath,String cellInfoFilePath,String imgOutputDirPath) throws IOException {
        List<String> lineList=NslUtilCsv.readCsvFile(new File(mrFilePath));
        int numBits=21;

        //<cellId,Set>: 其中set 包含： geoHash坐标系下的： geoHash点相对于 cell点的 ,x,y坐标
        Map<String,Set<NslPoint>> cellPointSet=new HashMap<>();
        for (int i = 1; i < lineList.size(); i++) {
            String[] array=lineList.get(i).split(",");
            String cellId=array[0];
            double cellLon=Double.parseDouble(array[1]);
            double cellLat=Double.parseDouble(array[2]);
            String geoHashString=array[3];
            double geoHashLon=Double.parseDouble(array[4]);
            double geoHashLat=Double.parseDouble(array[5]);
            GeoHash geoHash=new GeoHash(geoHashLon,geoHashLat,numBits);
            GeoHash cellGeoHash=new GeoHash(cellLon,cellLat,numBits);
            double originX=cellGeoHash.getGeoHashX();
            double originY=cellGeoHash.getGeoHashY();
            double hashX=geoHash.getGeoHashX();
            double hashY=geoHash.getGeoHashY();
            NslPoint point=new NslPoint(geoHash.getGeoHashString(),hashX-originX,hashY-originY);

            Set<NslPoint> pointSet=null;
            if(cellPointSet.containsKey(cellId)){
                pointSet=cellPointSet.get(cellId);
            }else{
                pointSet=new HashSet<>();
                cellPointSet.put(cellId,pointSet);
            }
            pointSet.add(point);
        }

        //根据 cell direction 旋转 坐标
        Map<String,WirelessCell> cellMap=readCellMap(cellInfoFilePath);
        Map<WirelessCell,Set<NslPoint>> cellPointSetMapAfterRotation=new HashMap<>();
        for (Map.Entry<String, Set<NslPoint>> stringSetEntry : cellPointSet.entrySet()) {
            String cellId=stringSetEntry.getKey();
            WirelessCell cell=cellMap.get(cellId);
            //转换成 弧度，逆时针
            double angle=cell.getDirectionAngle()/180*Math.PI;
            Set<NslPoint> beforeRotatedPointSet=stringSetEntry.getValue();
            Set<NslPoint> afterRotatedPointSet=new HashSet<>();
            for (NslPoint nslPoint : beforeRotatedPointSet) {
                NslPoint newPoint=rotationPointByAngle(nslPoint,-angle);
                afterRotatedPointSet.add(newPoint);
            }
            cellPointSetMapAfterRotation.put(cell,afterRotatedPointSet);
        }

        //创建图片 img点位图
        Map<WirelessCell,Set<NslPointLong>> cellImagePointMap=new HashMap<>();

        long width=80;
        long height=60;
        for (WirelessCell cell : cellPointSetMapAfterRotation.keySet()) {
            String id=cell.getId();
            Set<NslPoint> pointSet=cellPointSetMapAfterRotation.get(cell);
            Set<NslPointLong> imagePointSet=new HashSet<>();
            for (NslPoint nslPoint : pointSet) {
                NslPointLong pointLong= NslUtilGis.doublePoint2IntPoint(nslPoint);
                long imageX=(width-1)/2+pointLong.getX();
                long imageY=height- pointLong.getY()-1;
                NslPointLong imagePoint=new NslPointLong(pointLong.getId(),imageX,imageY);
                imagePointSet.add(imagePoint);
            }
            cellImagePointMap.put(cell,imagePointSet);
        }

//        String outputDir="D:\\GS_Dir_Ddisk\\GS#i3#Coding\\Test\\image\\";
//        outputDir="D:\\Deep_Learning\\Data\\images\\";

        int i=0;

        for (Map.Entry<WirelessCell, Set<NslPointLong>> wirelessCellSetEntry : cellImagePointMap.entrySet()) {
//            if(i==1000){
//                break;
//            }
            WirelessCell cell=wirelessCellSetEntry.getKey();
            Set<NslPointLong> pointLongSet=wirelessCellSetEntry.getValue();
            Map<NslPointLong,Integer> grayImageMap=new HashMap<>();

            for (NslPointLong pointLong : pointLongSet) {
                grayImageMap.put(pointLong,0xffffffff);
            }
            String outputFilePath=imgOutputDirPath+"\\"+cell.getId()+".jpg";

//            if(cell.getId().equals("1_11")){
//                creatGrayImage(outputFilePath, Math.toIntExact(width), Math.toIntExact(height),grayImageMap);
//            }
            creatGrayImage(outputFilePath, Math.toIntExact(width), Math.toIntExact(height),grayImageMap);
            i++;
        }
        return i;
    }


    private List<WirelessCell> lineList2WirelessCellList(List<String> lineList,int sectorAngle){
        List<WirelessCell> cellList=new ArrayList<>();
        for (int i = 1; i < lineList.size(); i++) {
            String line=lineList.get(i);
            String[] stringArray=line.split(",");
            String id=stringArray[0];
            double longitude=Double.parseDouble(stringArray[1]);
            double latitude=Double.parseDouble(stringArray[2]);
            double angle=Double.parseDouble(stringArray[3]);

            WirelessCell cell=new WirelessCell();
            cell.setId(id);
            cell.setLongitude(longitude);
            cell.setLatitude(latitude);
            cell.setDirectionAngle(angle);
            cell.setHorizontalBeam(sectorAngle);
            cell.setCoverRadius(500);

            cellList.add(cell);
        }
        return cellList;
    }


    private void initFont(){
        Font f = new Font("宋体", Font.PLAIN,12);

        String names[]={ "Label", "CheckBox", "PopupMenu","MenuItem", "CheckBoxMenuItem",
                "JRadioButtonMenuItem","ComboBox", "Button", "Tree", "ScrollPane",
                "TabbedPane", "EditorPane", "TitledBorder", "Menu", "TextArea",
                "OptionPane", "MenuBar", "ToolBar", "ToggleButton", "ToolTip",
                "ProgressBar", "TableHeader", "Panel", "List", "ColorChooser",
                "PasswordField","TextField", "Table", "Label", "Viewport",
                "RadioButtonMenuItem","RadioButton", "DesktopPane", "InternalFrame"
        };
        for (String item : names) {
            UIManager.put(item+ ".font",f);
        }
    }

    private void setScreenCenter(){

        int windowWidth = getWidth(); // 获得窗口宽
        int windowHeight = getHeight(); // 获得窗口高
        Toolkit kit = Toolkit.getDefaultToolkit(); // 定义工具包
        Dimension screenSize = kit.getScreenSize(); // 获取屏幕的尺寸
        int screenWidth = screenSize.width; // 获取屏幕的宽
        int screenHeight = screenSize.height; // 获取屏幕的高
        setLocation(screenWidth / 2 - windowWidth / 2, screenHeight / 2 - windowHeight / 2);// 设置窗口居中显示

    }

    public Map<String,WirelessCell> readCellMap(String cellFilePath) throws IOException {
        List<String> lineList=NslUtilCsv.readCsvFile(new File(cellFilePath));

        List<WirelessCell> wirelessCellList=lineList2WirelessCellList(lineList,0);

        Map<String,WirelessCell> cellMap=new HashMap<>();

        for (WirelessCell cell : wirelessCellList) {
            cellMap.put(cell.getId(),cell);
        }
        return  cellMap;
    }


    /**
     * 旋转 某个点，逆时针为负，顺时针为正
     * 角度 单位  弧度，即跟 π 有关系的那个单位
     * 公式： x1=x*cosA+y*sinA  y1=-x*sinA+y*cosA  x1,y1 为旋转后
     * @param originPoint 原始点
     * @param angle 旋转的角度，逆为负
     * @return
     */
    private NslPoint rotationPointByAngle(NslPoint originPoint,double angle){
        double x= originPoint.x();
        double y= originPoint.y();
        //旋转坐标,旋转角度 为 逆时针，旋转 小区方位角
        // x1=x*cosA+y*sinA  y1=-x*sinA+y*cosA
        double xAfterTurn=x*Math.cos(angle)+y*Math.sin(angle);
        double YAfterTurn=-x*Math.sin(angle)+y*Math.cos(angle);

        NslPoint newPoint=new NslPoint(originPoint.getId(),xAfterTurn,YAfterTurn);
        return newPoint;
    }

    /**
     * 根据 长、宽，和 pointGrayMap 生成图片
     * 默然点，gray=0;
     * 其中 pointGrayMap : <point,grayInt>
     * @param width
     * @param height
     * @param pointGrayMap
     */
    private void creatGrayImage(String outputFilePath,int width,int height,Map<NslPointLong,Integer> pointGrayMap) throws IOException {
        BufferedImage luminanceImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);

        Map<String, Integer> xYGrayMap=new HashMap<>();

        for (Map.Entry<NslPointLong, Integer> nslPointLongIntegerEntry : pointGrayMap.entrySet()) {
            NslPointLong pointLong=nslPointLongIntegerEntry.getKey();
            Integer gray=nslPointLongIntegerEntry.getValue();

            int pixel=0xff000000 | (gray << 16) | (gray << 8) | gray;
            pixel=0xffffffff;
            int x=Math.toIntExact(pointLong.getX());
            int y= Math.toIntExact(pointLong.getY());
            xYGrayMap.put(x+"_"+y,pixel);
        }

        //所有点默认为 0
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                int pixel=0xff000000 ;
                pixel=0x00000000;

                String xy=i+"_"+j;

                if(xYGrayMap.containsKey(xy)){
                    pixel=0x00ffffff;//白色
                }else{
                    pixel=0xff000000;//黑色
                }
//                log.info("i= {},j = {} , pixel = {}",i,j,pixel);
                luminanceImage.setRGB(i, j, pixel);

            }
        }

        ImageIO.write(luminanceImage, "jpg", new File(outputFilePath));
    }
}
